#include "camera_previewer_widget.h"
#include "ui_camera_previewer.h"
#include <qpushbutton.h>
#include <iostream>
#include <QMetaObject>
#include <QMutex>
#include <QQueue>
#include "logger.h"

CameraPreviewerWidget::CameraPreviewerWidget(QWidget* parent) :
    QWidget(parent),
    ui(new Ui::CameraPreviewerWidget)
{
    ui->setupUi(this);
    this->init_ctrl();
}

CameraPreviewerWidget::~CameraPreviewerWidget()
{
    delete ui;
}

void CameraPreviewerWidget::init_ctrl()
{
    devices_ = MFCameraDevice::enumerate();
    for (auto& device : devices_)
    {
        ui->cbx_device_list->addItem(QString::fromStdString(device->get_friendly_name()));
    }

    connect(ui->btnOpen, &QPushButton::clicked, this, &CameraPreviewerWidget::slot_btn_open);
    connect(ui->btnClose, &QPushButton::clicked, this, &CameraPreviewerWidget::slot_btn_close);
    connect(ui->cbx_device_list, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &CameraPreviewerWidget::slot_cbx_index_changed);

    slot_cbx_index_changed(0);
}

void CameraPreviewerWidget::paintEvent(QPaintEvent*)
{
}

void CameraPreviewerWidget::slot_btn_open()
{
    auto cbx_index = ui->cbx_device_list->currentIndex();
    auto res_index = ui->cbx_resolution->currentIndex();
    auto sup_res = devices_[cbx_index]->get_supported_resolutions();
    Resolution_1::shared res;
    for (int i = 0; i < sup_res.size(); ++i)
    {
        if (i == res_index)
        {
            res = sup_res[i];
        }
    }

    /* 摄像头采集器 */
    capturer_ = std::make_shared<MFCameraCapturer>();
    auto params = std::make_shared<MFCameraCapturerParams>();
    params->set_camera_device(devices_[cbx_index]);
    params->set_width(res->get_width());
    params->set_height(res->get_height());
    params->set_fps(res->get_frame_rate());
    params->set_cb([&](void* arg, IAVFrame::shared frame) {
        auto v_frame = std::dynamic_pointer_cast<D3d11VideoFrame>(frame);
        d3d_renderer_->render(v_frame);
    });
    capturer_->initialize(params);
    

    /* d3d渲染器 */
    d3d_renderer_ = std::make_shared<D3D11Renderer>();
    auto d3d_params = std::make_shared<D3D11RendererParams>();
    d3d_params->set_hwnd(HWND(ui->window->winId()));
    d3d_params->set_d3d11_device(params->get_d3d11_device().Get());
    d3d_params->set_d3d11_device_context(params->get_d3d11_device_context().Get());
    d3d_renderer_->initialize(d3d_params);

    capturer_->open();
}

void CameraPreviewerWidget::slot_btn_close()
{
    if (capturer_)
    {
        capturer_->close();
        capturer_->uninitialize();
        capturer_.reset();
    }

    if (d3d_renderer_)
    {
        d3d_renderer_->uninitialize();
        d3d_renderer_.reset();
    }
}

void CameraPreviewerWidget::slot_cbx_index_changed(int index)
{
    for (int i=0; i<devices_.size(); ++i)
    {
        if (i == index)
        {
            ui->cbx_resolution->clear();
            for (auto res : devices_[i]->get_supported_resolutions())
            {
                ui->cbx_resolution->addItem(
                    QString("%1 * %2 @ %3")
                    .arg(QString::number(res->get_width()))
                    .arg(QString::number(res->get_height()))
                    .arg(QString::number(res->get_frame_rate()))
                );
            }
            
        }
    }
}
